package com.example.springbootdockertest.controller.shopify;

import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 测试
 *
 * @Author liguangcheng
 * @Date 2021/8/8 4:50 下午
 * @Vision 1.0
 **/
@Slf4j
@Controller
public class ShopifyController {
    HashMap map = new HashMap();

    // https://tms-kec.kerry-ecommerce.com.cn/tms-saas-web/kerry/platform/shopify/callback?shop=lgc-test-lgc.myshopify.com
    // http://121.4.225.208:9999/platform/shopify/install?shop=lgc-test-lgc.myshopify.com
    // https://dev-cb-oms.kec-app.com/platform/shopify/install?shop=lgc-test-lgc.myshopify.com
    @RequestMapping(method = RequestMethod.GET, value = "/platform/shopify/install", produces = MediaType.APPLICATION_JSON_VALUE)
    public void shopifyInstall(HttpServletResponse response, @RequestParam String shop) throws Exception {
        String apiKey = "b9439da439c858620bfb8f2b51ea0e9a";
        String url = "https://" + shop + "/admin/oauth/authorize?client_id=" + apiKey + "&scope=read_orders,write_orders,write_shipping,read_products,write_inventory&redirect_uri=https://dev-cb-oms.kec-app.com/platform/shopify/callback";
        log.info("url-->{}", url);
        log.info("shop-->{};apiKey-->{}", shop, apiKey);
        response.sendRedirect(url);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/platform/shopify/callback")
    public String shopifyOauthCallBack(HttpServletResponse response, @RequestParam String shop, String code) throws Exception {
        String apiKey = "b9439da439c858620bfb8f2b51ea0e9a";
        String secret = "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";
        log.info("map-->{}", map);
        if (map.isEmpty()) {
            GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest();
            getAccessTokenRequest.setClientId(apiKey);
            getAccessTokenRequest.setClientSecret(secret);
            getAccessTokenRequest.setCode(code);
            log.info("auth参数：shop-->{};apiKey-->{},secret-->{},code-->{}", shop, apiKey, secret, code);

            ObjectMapper objectMapper = new ObjectMapper();
            String requestJson = objectMapper.writeValueAsString(getAccessTokenRequest);
            String authUrl = "https://" + shop + "/admin/oauth/access_token";
            String authResult = HttpRequest.post(authUrl).
                    body(requestJson, ContentType.JSON.toString()).
                    execute().
                    body();
            log.info("authUrl-->{};authResult-->{}", authUrl, authResult);
            GetAccessTokenResponse getAccessTokenResponse = objectMapper.readValue(authResult, GetAccessTokenResponse.class);
            String token = getAccessTokenResponse.getAccessToken();
            log.info("auth返回的token-->{}", token);
            //String webhooksCountUrl = getUrl(shop,"webhooks/count","");
            String webhooksCountUrl = "https://" + shop + "/admin/" + "webhooks/count" + ".json";
            String webhookCountResponse = HttpRequest.get(webhooksCountUrl).header("X-Shopify-Access-Token", token).header("Accept", "application/json").execute().body();
            //String webhookCountResponse = PlatformShopifyService.performShopifyRequest(shop, token, "webhooks/count", "", "GET");
            GetWebhooksCountResponse webhooksCountResult = objectMapper.readValue(webhookCountResponse, GetWebhooksCountResponse.class);
            log.info("webhooksCountUrl-->{};webhookCountResponse-->{},webhooksCountResult-->{}", webhooksCountUrl, webhookCountResponse, webhooksCountResult);
            if (webhooksCountResult.getCount() == 0) {
                List<String> topicList = new ArrayList<>();
                topicList.add("orders/cancelled");
                topicList.add("orders/create");
                topicList.add("orders/updated");
                topicList.add("orders/delete");
                topicList.add("app/uninstalled");
                //https://openapi.kec-app.com/platform/shopify/webhooks
                for (String topic : topicList) {
                    PostWebhooksRequest postWebhooksRequest = new PostWebhooksRequest();
                    PostWebhooksRequest.Webhook webhook = new PostWebhooksRequest.Webhook();
                    webhook.setTopic(topic);
                    webhook.setFormat("json");
                    webhook.setAddress("https://dev-cb-oms.kec-app.com/platform/shopify/webhooks");
                    postWebhooksRequest.setWebhook(webhook);
                    //String url = getUrl(shop, "webhooks", "");
                    String url = "https://" + shop + "/admin/" + "webhooks" + ".json";
                    //PlatformShopifyService.performShopifyRequest(shop, token, "webhooks", objectMapper.writeValueAsString(postWebhooksRequest), "POST");
                    String body = objectMapper.writeValueAsString(postWebhooksRequest);

                    String result = HttpRequest.post(url).
                            body(body, ContentType.JSON.toString()).
                            header("X-Shopify-Access-Token", token).header("Accept", "application/json").header("Content-Type", "application/json").
                            execute().
                            body();
                    log.info("body-->{},topic-->{};url-->{};result-->{}", body, topic, url, result);
                }
            }

            //String shopUrl = getUrl(shop, "shop", "");
            String shopUrl = "https://" + shop + "/admin/" + "shop" + ".json";
            String shopRes = HttpRequest.get(shopUrl).header("X-Shopify-Access-Token", token).execute().body();
            //String shopRes = PlatformShopifyService.performShopifyRequest(shop, token, "shop", "", "GET");
            GetShopResponse shopResponse = objectMapper.readValue(shopRes, GetShopResponse.class);
            ShopInfo shopInfo = new ShopInfo();
            shopInfo.setAccessToken(getAccessTokenResponse.getAccessToken());
            shopInfo.setCountry(shopResponse.getShop().getCountryCode());
            log.info("shopInfo", shopInfo);

            map.put("apiKey", apiKey);
            log.info("shopUrl-->{},shopRes-->{},shopResponse-->{}", shopUrl, shopRes, shopResponse);
            response.sendRedirect("https://" + shop + "/admin/apps/" + apiKey);
        }
        log.info("success--->success--->");
        return "installation";
    }

    @RequestMapping(method = RequestMethod.POST, value = "/platform/shopify/webhooks", produces = MediaType.APPLICATION_JSON_VALUE)
    public String webhooks(HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.info("进入/platform/shopify/webhooks");
        String shop = request.getHeader("x-shopify-shop-domain");
        String hmac = request.getHeader("x-shopify-hmac-sha256");
        String topic = request.getHeader("x-shopify-topic");
        String data = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

        log.info("shopify-webhooks shop: " + shop);
        log.info("shopify-webhooks hmac: " + hmac);
        log.info("shopify-webhooks topic: " + topic);
        log.info("data: " + data);

        log.info("success");
        return "success";

    }

    @RequestMapping(method = RequestMethod.GET, value = "/platform/shopify/callback1")
    public String shopifyOauthCallBack1(HttpServletResponse response, @RequestParam String shop, String code) throws Exception {
        //Optional<ConfigOrgDatasourceMapping> optionalConfigOrgDatasourceMapping = configOrgDatasourceMappingRepository.findByDatasourceTypeAndUsername("Shopify", shop);
        //if (optionalConfigOrgDatasourceMapping.isEmpty()) {
        //    ModelAndView modelAndView = new ModelAndView("installation-response");
        //    modelAndView.addObject("shop", shop);
        //    modelAndView.addObject("platform", "Shopify");
        //    modelAndView.addObject("error", true);
        //
        //    return modelAndView;
        //}

        //ConfigOrgDatasourceMapping configOrgDatasourceMapping = optionalConfigOrgDatasourceMapping.get();
        //if (!configOrgDatasourceMapping.getIsConnected()) {
        String apiKey = "b9439da439c858620bfb8f2b51ea0e9a";
        String secret = "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";
        log.info("shop-->{};apiKey-->{},secret-->{}", shop, apiKey, secret);
        GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest();
        getAccessTokenRequest.setClientId(apiKey);
        getAccessTokenRequest.setClientSecret(secret);
        getAccessTokenRequest.setCode(code);

        ObjectMapper objectMapper = new ObjectMapper();
        String requestJson = objectMapper.writeValueAsString(getAccessTokenRequest);
        //HttpRequest.post(url_).
        //                    body(json, ContentType.JSON.toString()).
        //                    header(key, token).
        //                    timeout(timeOut).
        //                    execute().
        //                    body();
        String authUrl = "https://" + shop + "/admin/oauth/access_token";
        String authResult = HttpRequest.post(authUrl).
                body(requestJson, ContentType.JSON.toString()).
                execute().
                body();
        log.info("authUrl-->{};authResult-->{}", authUrl, authResult);
        GetAccessTokenResponse getAccessTokenResponse = objectMapper.readValue(authResult, GetAccessTokenResponse.class);
        String token = getAccessTokenResponse.getAccessToken();
        log.info("返回的token-->{}", token);


        //OkHttpClient okHttpClient = new OkHttpClient();
        //Request request = new Request.Builder().url("https://" + shop + "/admin/oauth/access_token").post(RequestBody.create(requestJson, JSON)).build();
        //
        //Response shopifyResponse = okHttpClient.newCall(request).execute();
        //
        //GetAccessTokenResponse getAccessTokenResponse = objectMapper.readValue(shopifyResponse.body().string(), GetAccessTokenResponse.class);
        //String token = getAccessTokenResponse.getAccessToken();

        String webhooksCountUrl = getUrl(shop, "webhooks/count", "");
        String webhookCountResponse = HttpRequest.get(webhooksCountUrl).header("X-Shopify-Access-Token", token).execute().body();
        //String webhookCountResponse = PlatformShopifyService.performShopifyRequest(shop, token, "webhooks/count", "", "GET");
        GetWebhooksCountResponse webhooksCountResult = objectMapper.readValue(webhookCountResponse, GetWebhooksCountResponse.class);
        log.info("webhooksCountUrl-->{};webhookCountResponse-->{},webhooksCountResult-->{}", webhooksCountUrl, webhookCountResponse, webhooksCountResult);
        if (webhooksCountResult.getCount() == 0) {
            List<String> topicList = new ArrayList<>();
            topicList.add("orders/cancelled");
            topicList.add("orders/create");
            topicList.add("orders/updated");
            topicList.add("orders/delete");
            topicList.add("app/uninstalled");
            for (String topic : topicList) {
                PostWebhooksRequest postWebhooksRequest = new PostWebhooksRequest();
                PostWebhooksRequest.Webhook webhook = new PostWebhooksRequest.Webhook();
                webhook.setTopic(topic);
                webhook.setFormat("json");
                webhook.setAddress("121.4.225.208:9999/platform/shopify/webhooks");
                postWebhooksRequest.setWebhook(webhook);
                String url = getUrl(shop, "webhooks", "");
                //PlatformShopifyService.performShopifyRequest(shop, token, "webhooks", objectMapper.writeValueAsString(postWebhooksRequest), "POST");
                String result = HttpRequest.post(url).
                        body(objectMapper.writeValueAsString(postWebhooksRequest), ContentType.JSON.toString()).
                        header("X-Shopify-Access-Token", token).header("Accept", "application/json").header("Content-Type", "application/json").
                        execute().
                        body();
                log.info("topic-->{};url-->{};result-->{}", topic, url, result);
            }
        }

        String shopUrl = getUrl(shop, "shop", "");
        String shopRes = HttpRequest.get(shopUrl).header("X-Shopify-Access-Token", token).execute().body();
        //String shopRes = PlatformShopifyService.performShopifyRequest(shop, token, "shop", "", "GET");
        GetShopResponse shopResponse = objectMapper.readValue(shopRes, GetShopResponse.class);
        log.info("shopUrl-->{},shopResponse-->{},shopResponse-->{}", shopUrl, shopRes, shopResponse);
        //
        //ConfigOrgDatasourceMapping.ShopInfo shopInfo = new ConfigOrgDatasourceMapping.ShopInfo();
        //shopInfo.setAccessToken(getAccessTokenResponse.getAccessToken());
        //shopInfo.setCountry(shopResponse.getShop().getCountryCode());
        //
        //configOrgDatasourceMapping.setShopInfo(shopInfo);
        //configOrgDatasourceMapping.setIsConnected(true);
        //configOrgDatasourceMappingRepository.save(configOrgDatasourceMapping);
        response.sendRedirect("https://" + shop + "/admin/apps/" + apiKey);
        //}
        ModelAndView modelAndView = new ModelAndView("index");
        //modelAndView.addObject("shop", shop);
        //modelAndView.addObject("platform", "Shopify");
        //modelAndView.addObject("success", true);
        log.info("success--->success--->");
        return "<html>\n" +
                "\n" +
                "\n" +
                "\n" +
                "<div>\n" +
                "    \n" +
                "        success\n" +
                "    \n" +
                "</div>\n" +
                "\n" +
                "\n" +
                "</html>";
    }

    private String getUrl(String shop, String resource, String params) {
        String webhooksUrl = "https://" + shop + "/admin/" + resource + ".json";
        if (!params.equals("")) {
            webhooksUrl = webhooksUrl + "?" + params;
        }
        return webhooksUrl;
    }

    @Data
    public static class ShopInfo {
        @JsonProperty("accessToken")
        String accessToken;

        @JsonProperty("country")
        String country;

        @JsonProperty("refreshToken")
        String refreshToken;

        @JsonProperty("refreshTokenExpireAt")
        String refreshTokenExpireAt;

        @JsonProperty("tokenExpireAt")
        String tokenExpireAt;

        @JsonProperty("account")
        String account;

        @JsonProperty("userId")
        String userId;

        @JsonProperty("sellerId")
        String sellerId;

        @JsonProperty("shortCode")
        String shortCode;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class GetAccessTokenRequest {
        @JsonProperty("client_id")
        private String clientId;
        @JsonProperty("client_secret")
        private String clientSecret;
        @JsonProperty("code")
        private String code;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class GetWebhooksCountResponse {
        @JsonProperty("errors")
        private String errors;

        @JsonProperty("count")
        private Integer count;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class PostWebhooksRequest {
        @JsonProperty("webhook")
        private Webhook webhook;

        @Data
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class Webhook {
            @JsonProperty("topic")
            private String topic;

            @JsonProperty("address")
            private String address;

            @JsonProperty("format")
            private String format;
        }
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class GetShopResponse {
        @JsonProperty("shop")
        private Shop shop;

        @Data
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class Shop {
            @JsonProperty("address1")
            private String address1;

            @JsonProperty("address2")
            private String address2;

            @JsonProperty("city")
            private String city;

            @JsonProperty("country_code")
            private String countryCode;

            @JsonProperty("domain")
            private String domain;

            @JsonProperty("email")
            private String email;

            @JsonProperty("name")
            private String name;

            @JsonProperty("phone")
            private String phone;

            @JsonProperty("zip")
            private String zip;

            @JsonProperty("province")
            private String province;
        }
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class GetAccessTokenResponse {
        @JsonProperty("access_token")
        private String accessToken;
    }

}
